package wang.aweb.childcar.filter;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.beans.factory.annotation.Autowired;
import wang.aweb.childcar.common.Constant;
import wang.aweb.childcar.exception.CarException;
import wang.aweb.childcar.exception.CarExceptionEnum;
import wang.aweb.childcar.model.pojo.Administrator;
import wang.aweb.childcar.model.pojo.Agent;
import wang.aweb.childcar.service.AdministratorService;
import wang.aweb.childcar.service.MemberService;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;

public class AdminFilter  implements Filter {
    private static final List<String> ALLOWED_PATHS= Arrays.asList("/management/administrator/login","/management/administrator/info");
    @Autowired
    private AdministratorService administratorService;
    public static ThreadLocal<Administrator> administratorThreadLocal=new ThreadLocal();
    public Administrator currentAdministrator=new Administrator();

    public Administrator getCurrentAdministrator() {
        return currentAdministrator;
    }

    public void setCurrentAdministrator(Administrator currentAdministrator) {
        this.currentAdministrator = currentAdministrator;
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request=(HttpServletRequest) servletRequest;
        String token=request.getHeader("token");
        System.out.println(token);
        String path=request.getRequestURI().substring(request.getContextPath().length()).replaceAll("[/]+$","");
        Boolean allowPath=ALLOWED_PATHS.contains(path);
        if(allowPath==false){
            if(token==null){
                PrintWriter out=new HttpServletResponseWrapper((HttpServletResponse)servletResponse).getWriter();
                out.write("{\n" +
                        "    \"code\": 10007,\n" +
                        "    \"msg\": \"NEED_JWT_TOKEN\",\n" +
                        "    \"data\": null\n" +
                        "}");
                out.flush();
                out.close();
                return;
            }

            Algorithm algorithm=Algorithm.HMAC256(Constant.JWT_KEY);

            JWTVerifier jwtVerifier= JWT.require(algorithm).build();
            try{
                DecodedJWT jwt=jwtVerifier.verify(token);
                currentAdministrator=new Administrator();
                if(jwt.getClaim(Constant.USER_ROLE).asInt()==3){
                    currentAdministrator.setId(jwt.getClaim(Constant.USER_ID).asInt());
                    administratorThreadLocal.set(currentAdministrator);
                }else{
                    throw new CarException(CarExceptionEnum.NEED_ADMIN);
                }
            }catch (TokenExpiredException e){
                throw new CarException(CarExceptionEnum.TOKEN_EXPIRED);
            }catch (JWTDecodeException e){
                throw new CarException(CarExceptionEnum.TOKEN_WRONG);
            }catch (Exception e){
                throw new CarException(CarExceptionEnum.SYSTEM_ERROR);
            }
        }

        filterChain.doFilter(servletRequest,servletResponse);
    }
    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
